package com.example.weather;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;

import java.util.ArrayList;

public class DrawDayWeather extends View
{
	private Context mContext;

	private int refresh_rate = 24;//刷新率
	private long refresh_cycle = 1000 / refresh_rate;//帧间隔时间
	//在 activity 中调用 getWindowManager().getDefaultDisplay().getRefreshRate() 可以获得屏幕刷新率

	private int mWidth;//屏幕的宽度
	private int mHeight;//屏幕的高度
	private final int SIZE_DATA = 5;//一个屏幕的宽度，显示的数据个数
	private int Date_Data_x;//两个数据之间的横向间隔
	private int Date_Data_y;//两个数据之间的竖向间隔

	private int x_scroll;//x轴原点的位置相对于屏幕的位置
	private int y_scroll;//x轴原点的位置相对于屏幕的位置

	private int max_xScroll;//限制图像向X的正半轴移动
	private int min_xScroll;//限制图像向负半轴运动

	private int max_yScroll;//限制图像向X的正半轴移动
	private int min_yScroll;//限制图像向负半轴运动

	private int bigCircleR = 7; //折线图中的圆圈
	private int smallCircleR = 5; //折线图中为了避免折线穿透的圆圈
	private Paint paintWhite, paintBlue, paintRed, paintBack, paintText, dashPaint, paintTime;
	private int xyTextSize = sp2px(10); //xy轴文字大小
	private GestureDetector gestureDetector; //滑动手势

	DrawLineData[] drawLineData = null;
	String[][] str_data = null;
	Bitmap[] bitmap_list = null;
	final int str_data_ = 5;//字符串数据类型的数量
	final int str_data__ = 30;//这个数必须小于6*8，大于6*8会有未知错误
	final int drawLineData_ = 6;
	final int y_count_in_mHeight = 6;//屏幕分给的区域，显示几行数据
	final int x_count_in_mWidth = 6;//屏幕分给的区域，显示几行数据
	final int time_aDay_Datas = 8;//我爬的天气预报一天只有8个时刻的天气详情

	//储存一周的天气粗略信息
	DrawLineData week_lowtmp_drawLineData, week_hightmp_drawLineData;
	Bitmap[][] week_bitmap_list;
	String[][] week_date;

	/*计算单个数据展示的宽和高
	修改两个变量的值
	Date_Data_x
	Date_Data_y
	调用api获取屏幕分辨率
	 */
	void new_Data_Data_distance()
	{
		//mWidth = getWidth();
		//mHeight = getHeight();
		Log.e("TAG", "new_Data_Data_distance: mWidth  " + mWidth + "  mHeight   " + mHeight);
		Date_Data_x = mWidth / x_count_in_mWidth;
		Date_Data_y = mHeight / y_count_in_mHeight;
	}

	void new_max_min_xScroll()//重新计算x轴可移动的范围
	{
		max_xScroll = Date_Data_x / 2;
		if (drawLineData == null)//不允许左右滑动
		{
			//max_xScroll=0;
			min_xScroll = 0;
			return;
		}
		if (str_data__ < SIZE_DATA)
		{
			min_xScroll = 0;
		}
		else
		{
			min_xScroll = -Date_Data_x * (drawLineData[0].data.length - SIZE_DATA + 1);
		}
	}

	void new_max_min_yScroll()//重新计算y轴可移动的范围
	{
		max_yScroll = Date_Data_y / 2;
		if (drawLineData == null)//不允许左右滑动
		{
			//max_xScroll=0;
			min_yScroll = 0;
			return;
		}
		if (drawLineData.length < y_count_in_mHeight)
		{
			min_yScroll = 0;
		}
		else
		{
			min_yScroll = -Date_Data_y * (drawLineData.length - y_count_in_mHeight + 5);
		}
	}

	public void setRefresh_rate(float refresh_rate)
	{
		this.refresh_rate = (int) (refresh_rate / 1);
		this.refresh_cycle = 1000 / this.refresh_rate;
	}

	public DrawDayWeather(Context context)
	{
		super(context);
	}

	public DrawDayWeather(Context context, @Nullable AttributeSet attrs)
	{
		this(context, attrs, 0);
	}

	public DrawDayWeather(Context context, @Nullable AttributeSet attrs, int defStyleAttr)
	{
		super(context, attrs, defStyleAttr);
		mContext = context;
		initPaint();
		gestureDetector = new GestureDetector(context, new MyOnGestureListener());//手势事件
	}

	/*
	规定线的粗细颜色等内容
	 */
	private void initPaint()
	{
		paintWhite = new Paint(Paint.ANTI_ALIAS_FLAG);
		paintWhite.setColor(Color.WHITE);
		paintWhite.setStyle(Paint.Style.STROKE);

		paintBlue = new Paint(Paint.ANTI_ALIAS_FLAG);
		paintBlue.setColor(Color.parseColor("#0198cd"));
		paintBlue.setStrokeWidth(3f);
		paintBlue.setStyle(Paint.Style.STROKE);

		paintBack = new Paint(Paint.ANTI_ALIAS_FLAG);
		paintBack.setColor(Color.parseColor("#272727"));
		paintBack.setStyle(Paint.Style.FILL);

		paintRed = new Paint(Paint.ANTI_ALIAS_FLAG);
		paintRed.setColor(Color.RED);
		paintRed.setStrokeWidth(3f);
		paintRed.setStyle(Paint.Style.STROKE);

		paintText = new Paint(Paint.ANTI_ALIAS_FLAG);
		paintText.setColor(Color.WHITE);
		paintText.setTextSize(xyTextSize);
		paintText.setStrokeWidth(2f);

		paintTime = new Paint(Paint.ANTI_ALIAS_FLAG);
		paintTime.setColor(Color.parseColor("#FF00FF"));
		paintTime.setTextSize(xyTextSize);
		paintTime.setStrokeWidth(2f);

		dashPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
		dashPaint.setColor(Color.WHITE);
		dashPaint.setStyle(Paint.Style.STROKE);
		dashPaint.setStrokeWidth(1f);
	}

	/*查找字符串数组里是否有要查找的字符串，
	k 查找的范围
	 */
	private boolean String_in_Strings(int k, String[] strings, String str1)
	{
		//for (String str2 : strings)
		for (int i = k; i < strings.length; i++)
		{
			if (str1.equals(strings[i]))
			{
				return true;
			}
		}
		return false;
	}

	/*
	为这个视图类填充数据
	 */
	public void setYValues(ArrayList<DayWeatherData> dayweather)
	{
		if (dayweather.size() == 0)
		{
			return;//清除旧数据
		}
		//处理周 粗略信息
		week_hightmp_drawLineData = new DrawLineData("温度", "°C", dayweather.size(), "#CD5C5C");
		week_lowtmp_drawLineData = new DrawLineData("温度", "°C", dayweather.size(), "#0198cd");
		week_bitmap_list = new Bitmap[2][dayweather.size()];//一周每天有两个天气图片
		week_date = new String[2][dayweather.size()];
		week_hightmp_drawLineData.min = 100;//给最小值一个大值，给最大值一个小值，确保在更新数据的时候能重新确定范围。
		week_hightmp_drawLineData.max = -100;
		for (int k = 0; k < dayweather.size(); k++)
		{
			week_hightmp_drawLineData.data[k] = Float.parseFloat(dayweather.get(k).day_high);
			week_lowtmp_drawLineData.data[k] = Float.parseFloat(dayweather.get(k).day_low);
			week_bitmap_list[0][k] = dayweather.get(k).bitmap[0];
			week_bitmap_list[1][k] = dayweather.get(k).bitmap[1];
			week_date[0][k] = dayweather.get(k).day_name_week;
			week_date[1][k] = dayweather.get(k).day_name_number;
			//Log.i(TAG, "setYValues: aDay.high  " + aDay.high);
			//Log.i(TAG, "setYValues: aDay.low  " + aDay.low);
			if (week_hightmp_drawLineData.data[k] > week_hightmp_drawLineData.max)
			{
				week_hightmp_drawLineData.max = week_hightmp_drawLineData.data[k];
			}
			if (week_lowtmp_drawLineData.data[k] < week_hightmp_drawLineData.min)
			{
				week_hightmp_drawLineData.min = week_lowtmp_drawLineData.data[k];
			}
			if (week_lowtmp_drawLineData.data[k] > week_hightmp_drawLineData.max)
			{
				week_hightmp_drawLineData.max = week_lowtmp_drawLineData.data[k];
			}
			if (week_hightmp_drawLineData.data[k] < week_hightmp_drawLineData.min)
			{
				week_hightmp_drawLineData.min = week_hightmp_drawLineData.data[k];
			}
		}
		if (week_hightmp_drawLineData.max - week_hightmp_drawLineData.min < 2)
		{
			week_hightmp_drawLineData.max = week_hightmp_drawLineData.max + 1;//当最大值最小值差值为1时，最大值的描点会出现问题,所以在这里强行制造最大值和最小值的差值
		}
		week_lowtmp_drawLineData.min = week_hightmp_drawLineData.min;
		week_lowtmp_drawLineData.max = week_hightmp_drawLineData.max;

		//处理日 详细信息
		drawLineData = new DrawLineData[drawLineData_];//5类数据每类数据12条
		str_data = new String[str_data_][str_data__];//4类数据每类数据12条
		bitmap_list = new Bitmap[str_data__];
		int k = 0;//条目
		drawLineData[0] = new DrawLineData("气温", "°C", str_data__, "#CD5C5C");
		drawLineData[1] = new DrawLineData("风速", "m/s", str_data__, "#00FF7F");
		drawLineData[2] = new DrawLineData("气压", "hpa", str_data__, "#6E6E6E");
		drawLineData[3] = new DrawLineData("湿度", "%", str_data__, "#4F94CD");
		drawLineData[4] = new DrawLineData("云量", "%", str_data__, "#FFFFFF");
		drawLineData[5] = new DrawLineData("降水", "mm", str_data__, "#4F94CD");
		String last_date = "";
		int pian_yi = 0;//第一天有时候会显示第二天的天气，这里是计算偏移值使用的
		for (DayWeatherData xdayweather : dayweather)
		{
			for (TimeWeatherData xtimeWeatherDatas : xdayweather.timeWeatherDatas)
			{
				if (k == str_data__)
				{
					break;
				}
				else if (String_in_Strings(k >= time_aDay_Datas ? k - time_aDay_Datas + 1 : 0, str_data[0], xtimeWeatherDatas.time))
				{
					pian_yi = pian_yi + 1;
					continue;
				}
				if (!last_date.equals(xdayweather.day_name_number))
				{
					str_data[4][k - pian_yi] = xdayweather.day_name_number + " " + xdayweather.day_name_week;
					last_date = xdayweather.day_name_number;
				}
				pian_yi = 0;
				str_data[0][k] = xtimeWeatherDatas.time;
				str_data[1][k] = xtimeWeatherDatas.weather_img;
				str_data[2][k] = xtimeWeatherDatas.feng_xiang;
				str_data[3][k] = xtimeWeatherDatas.jiang_shui_liang;
				bitmap_list[k] = xtimeWeatherDatas.bitmap_img;
				drawLineData[0].data[k] = xtimeWeatherDatas.temperature_float;//new DrawLineData("气温","°C",12);
				drawLineData[1].data[k] = xtimeWeatherDatas.feng_su_float;//new DrawLineData("风速","°C",12);
				drawLineData[2].data[k] = xtimeWeatherDatas.qi_ya_int;//new DrawLineData("气压","°C",12);
				drawLineData[3].data[k] = xtimeWeatherDatas.humidity_int;//new DrawLineData("湿度","°C",12);
				drawLineData[4].data[k] = xtimeWeatherDatas.yun_liang_float;//new DrawLineData("云量","°C",12);
				drawLineData[5].data[k] = xtimeWeatherDatas.jiang_shui_liang_float;//new DrawLineData("降水", "mm", str_data__, "#4F94CD");
				k++;
			}
			if (k == str_data__)
			{
				break;
			}
		}
		for (int i = 0; i < drawLineData_; i++)
		{
			drawLineData[i].min = drawLineData[i].data[0];
			drawLineData[i].max = drawLineData[i].data[0];
		}
		for (int j = 1; j < str_data__; j++)
		{
			for (int i = 0; i < drawLineData_; i++)
			{
				if (drawLineData[i].data[j] > drawLineData[i].max)
				{
					drawLineData[i].max = drawLineData[i].data[j];
				}
				else if (drawLineData[i].data[j] < drawLineData[i].min)
				{
					drawLineData[i].min = drawLineData[i].data[j];
				}
			}
			//Log.i("", "		" + drawLineData[0].data[j] + "		" + drawLineData[1].data[j] + "		" + drawLineData[2].data[j] + "		" + drawLineData[3].data[j] + drawLineData[4].data[j]);
		}
		for (int i = 0; i < drawLineData.length; i++)
		{
			//drawLineData[i].min = drawLineData[i].min - 1;//因为浮点之后要取整，舍去会导致比例计算出错，所以提前加一
			drawLineData[i].max = (float) (drawLineData[i].max + (drawLineData[i].max - drawLineData[i].min) * 0.1);
			drawLineData[i].min = (float) (drawLineData[i].min - (drawLineData[i].max - drawLineData[i].min) * 0.3);
			//Log.i("TAG", "setYValues: drawLineData[" + i + "].max  " + drawLineData[i].max + "   drawLineData[" + i + "].min   " + drawLineData[i].min);
		}

		for (int j = 0; j < str_data__; j++)
		{
			Log.i("", "		" + str_data[0][j] + "		" + str_data[1][j] + "		" + str_data[2][j] + "		" + str_data[3][j]);
		}
		for (int j = 0; j < str_data__; j++)
		{
			Log.i("", "		" + drawLineData[0].data[j] + "		" + drawLineData[1].data[j] + "		" + drawLineData[2].data[j] + "		" + drawLineData[3].data[j] + "		" + drawLineData[4].data[j] + "		" + drawLineData[5].data[j]);
		}

		new_max_min_xScroll();//重新计算x轴可移动的范围
		new_max_min_yScroll();//重新计算y轴可移动的范围
	}

	/*
	视图初始化时会调用此函数
	 */
	@Override
	protected void onLayout(boolean changed, int left, int top, int right, int bottom)
	{
		if (changed)
		{
			mWidth = getWidth();
			mHeight = getHeight();
			new_Data_Data_distance();//计算数据图像占用的宽高大小

			x_scroll = Date_Data_x / 2;//初始时将图像向屏幕的右面移动半个数据间隔
			new_max_min_xScroll();//计算x轴可移动的范围
			new_max_min_yScroll();//计算x轴可移动的范围
		}
		super.onLayout(changed, left, top, right, bottom);
	}


	//折现的数据储存类
	class DrawLineData
	{
		String data_name;
		String data_units;
		int color;

		float data[];
		float max = Float.MAX_VALUE;
		float min = Float.MIN_VALUE;

		public DrawLineData(String data_name, String data_units, int SIZE_data, String color)
		{
			this.data_name = data_name;
			this.data_units = data_units;
			data = new float[SIZE_data];
			this.color = Color.parseColor(color);
		}
	}


	@Override
	protected void onDraw(Canvas canvas)
	{
//		super.onDraw(canvas);
//		Path path = new Path();
//		绘制折线//单日最高温折线
//		path.moveTo(x_scroll, mHeight);
//		path.lineTo(0,0);
//		canvas.drawPath(path, paintRed);
//		canvas.drawBitmap(11,1);
//		Log.i("TAG", "onDraw: ");

		/*
		top_need 顶线
		bottom_need 底线
		 */
		if (drawLineData == null || str_data == null || str_data[0][0] == null || str_data[0][0].equals(""))
		{
			Log.e("TAG", "onDraw   str_data==null: ");
			return;
		}
		//Log.e("TAG", "onDraw   str_data!=null: ");
		int top_need = getTextHeight(paintText, "00.00");//顶部坐标
		int bottom_need;//单个线条的底部坐标
		final int row_height = mHeight / y_count_in_mHeight;//屏幕分到的区域显示三个数据//该值为单个数据线条的高度

		top_need = top_need + y_scroll;
		//Log.i("TAG", "onDraw: draw_week_weather top: " + top_need);
		final int week_high = draw_week_weather(canvas, top_need);
		top_need = top_need + week_high;//绘制一周的粗略信息，然后将
		//Log.i("TAG", "onDraw: draw_week_weather bottom " + top_need);
		//Log.i("TAG", "onDraw: draw_week_weather y_scroll " + y_scroll);
		//Log.i("TAG", "onDraw: draw_week_weather week_high " + week_high);
		final int top_need_time_text = top_need + Date_Data_x / 2;//保存这个坐标，预留给日详细天气的小时标记
		top_need = top_need + Date_Data_x;//周粗略信息和日详细信息的分界区域
		bottom_need = top_need + row_height * 2 / 3;


		draw_bitmap(canvas, bottom_need, top_need, 0, bitmap_list);
		top_need = top_need + row_height * 2 / 3;
		bottom_need = row_height + top_need;

		//绘制一些数据的折线和标题
		for (int i = 0; i < drawLineData.length; i++)
		{
			drawLine1_AndTitle(canvas, bottom_need, top_need, drawLineData[i]);
			top_need = top_need + row_height;
			bottom_need = top_need + row_height;
		}

		//绘制日小时文字标注
		if (top_need_time_text < 0)
		{
			drawTextOnLine(canvas, str_data[0], Date_Data_x, 5 * getTextHeight(paintText, "00.00") / 2, Date_Data_x / 6, paintTime);
			drawTextOnLine(canvas, str_data[4], Date_Data_x, getTextHeight(paintText, "00.00"), Date_Data_x / 6, paintTime);
		}
		else
		{
			drawTextOnLine(canvas, str_data[0], Date_Data_x, top_need_time_text + 5 * getTextHeight(paintText, "00.00") / 2, Date_Data_x / 6, paintTime);
			drawTextOnLine(canvas, str_data[4], Date_Data_x, top_need_time_text + getTextHeight(paintText, "00.00"), Date_Data_x / 6, paintTime);
		}


	}

	/*
	绘制周粗略数据
	返回自己占用的空间的高度值
	 */
	private int draw_week_weather(Canvas canvas, int top_need)
	{
		int count_high = 0;
		count_high = count_high + drawTextOnLine(canvas, week_date[0], Date_Data_x, top_need + count_high, Date_Data_x / 3, paintText) + getTextHeight(paintText, "00.00");
		count_high = count_high + drawTextOnLine(canvas, week_date[1], Date_Data_x, top_need + count_high, Date_Data_x / 3, paintText) + getTextHeight(paintText, "00.00");
		count_high = count_high + draw_bitmap(canvas, top_need + Date_Data_x + count_high, top_need + count_high, 0, week_bitmap_list[0]);

		int bottom_need;
		bottom_need = top_need + count_high + Date_Data_x * 3 / 2;
		drawLine1(canvas, bottom_need, top_need + count_high, week_hightmp_drawLineData);
		drawLine1(canvas, bottom_need, top_need + count_high, week_lowtmp_drawLineData);
		count_high = count_high + Date_Data_x * 3 / 2;

		count_high = count_high + draw_bitmap(canvas, top_need + Date_Data_x + count_high, top_need + count_high, 0, week_bitmap_list[1]);

		return count_high;
	}

	/*绘制一行大小相同的图片
	该函数对此程序进行过适配，无法直接拿走调用
	Canvas canvas		绘图类
	int bottom_need		底线
	int top_need		顶线
	int start_X			行首缩进
	Bitmap[] bitmap_list图片数组
	返回自己高度的大小
	*/
	private int draw_bitmap(Canvas canvas, int bottom_need, int top_need, int start_X, Bitmap[] bitmap_list)
	{
		int img_start_x;
		int img_end_x;
		for (int i = 0; i < bitmap_list.length; i++)
		{
			img_start_x = i * Date_Data_x + start_X + x_scroll - Date_Data_x / 2;
			img_end_x = img_start_x + bottom_need - top_need;
			//Log.e("TAG", "drawLine  1111: ");
			if (bitmap_list[i] != null)
			{
				Rect rect = new Rect(img_start_x, top_need, img_end_x, bottom_need);
				//两对数据，确定两个坐标，确定一个矩形。
				//Log.e("TAG", "drawLine  1111: ");
				canvas.drawBitmap(bitmap_list[i], null, rect, null);
				//Log.e("TAG", "drawLine  2222: ");
			}
		}
		return bottom_need - top_need;
	}

	/*写两行字
	时间
	08：00  11：00 …………
	Canvas canvas       绘图类
	String[] strings    要绘制的字符串数组
	int Text_Text       两个文字之间的横向距离
	int top_need
	String name_title
	 */
	private int drawTextOnLine_AndTitle(Canvas canvas, String[] strings, int Text_Text, int top_need, int start_X, String name_title, Paint paintText)//绘制折线和折线的总标题
	{
		canvas.drawText(name_title, start_X + x_scroll - dip2px(25), top_need, paintText);
		top_need = top_need + getTextHeight(paintText, "00.00");
		for (int i = 0; i < strings.length; i++)
		{
			//Log.e("TAG", "strings  "+i+": "+strings[i]);
			if (strings[i] == null || strings[i].equals(""))
			{
				continue;
			}
			canvas.drawText(strings[i], start_X + x_scroll + i * Text_Text - dip2px(25), top_need + getTextHeight(paintText, "00.00"), paintText);
			//Log.e("TAG", "onDraw  8: ");
		}
		return getTextHeight(paintText, "00.00");//返回新的top_need
	}

	/*写一行字
	08：00  11：00 …………
	Canvas canvas       绘图类
	String[] strings    要绘制的字符串数组
	int Text_Text       两个文字之间的横向距离
	int top_need
	int start_X			行首缩进值
	 */
	private int drawTextOnLine(Canvas canvas, String[] strings, int Text_Text, int top_need, int start_X, Paint paintText)//绘制折线和折线的总标题
	{
		for (int i = 0; i < strings.length; i++)
		{
			//Log.e("TAG", "strings  "+i+": "+strings[i]);
			if (strings[i] == null)
			{
				continue;
			}
			canvas.drawText(strings[i], start_X + x_scroll + i * Text_Text - dip2px(25), top_need + getTextHeight(paintText, "00.00"), paintText);
		}
		return getTextHeight(paintText, "00.00");//返回新的top_need
	}

	//绘制数据线条和标题
	private void drawLine1_AndTitle(Canvas canvas, int bottom_need, int top_need, DrawLineData _drawLineData)//绘制折线和折线的总标题
	{
		canvas.drawText(_drawLineData.data_name + "/" + _drawLineData.data_units, dip2px(25), top_need + getTextHeight(paintText, "00.00"), paintText);
		drawLine1(canvas, bottom_need, top_need + getTextHeight(paintText, "00.00"), _drawLineData);
	}

	/*绘制折线和折线点的数据
	Canvas canvas               画图类
	int bottom_need             折线的底部坐标
	int top_need                折线的顶部坐标
	DrawLineData _drawLineData  折线数据类，包含数据的标题、单位、数值数组
	*/
	private void drawLine1(Canvas canvas, int bottom_need, int top_need, DrawLineData _drawLineData)
	{
		if (_drawLineData == null)
		{
			return;
		}
//        if (BuildConfig.DEBUG && mHeight <= bottom_need)
//        {
//            throw new AssertionError("DrawDayWeather.drawLine1() 中，出现 mHeight < (bottom_need + top_need) ");
//        }
		float aver = (bottom_need - top_need) / (_drawLineData.max - _drawLineData.min); //y轴最小单位的距离
		int i = 0;

		Paint paint;
		paint = new Paint(Paint.ANTI_ALIAS_FLAG);
		paint.setColor(_drawLineData.color);
		paint.setStrokeWidth(3f);
		paint.setStyle(Paint.Style.STROKE);
		Path path = new Path();

		path.moveTo(x_scroll, bottom_need - (aver * (_drawLineData.data[0] - _drawLineData.min)));
		for (float xdata : _drawLineData.data)
		{
			path.lineTo(x_scroll + i * Date_Data_x, bottom_need - (aver * (xdata - _drawLineData.min)));
			canvas.drawCircle(x_scroll + i * Date_Data_x, bottom_need - (aver * (xdata - _drawLineData.min)), bigCircleR, paint);
			canvas.drawCircle(x_scroll + i * Date_Data_x, bottom_need - (aver * (xdata - _drawLineData.min)), smallCircleR, paintBack);

			i++;
		}
		canvas.drawPath(path, paint);//将线条连起来

		//绘制折线折点圆圈
		i = 0;
		for (float xdata : _drawLineData.data)
		{
			canvas.drawCircle(x_scroll + i * Date_Data_x, bottom_need - (aver * (xdata - _drawLineData.min)), bigCircleR, paint);
			canvas.drawCircle(x_scroll + i * Date_Data_x, bottom_need - (aver * (xdata - _drawLineData.min)), smallCircleR, paintBack);
			if (bottom_need - (aver * (xdata - _drawLineData.min)) -  getTextHeight(paintText, "00.00") < top_need)
			{
				canvas.drawText(String.valueOf(xdata), x_scroll + i * Date_Data_x+dip2px(8), top_need + getTextHeight(paintText, "00.00"), paintText);
			}
			else
			{
				canvas.drawText(String.valueOf(xdata), x_scroll + i * Date_Data_x+dip2px(8), bottom_need - (aver * (xdata - _drawLineData.min)), paintText);
			}
			i++;
		}

	}


	/*
		移交触摸事件的处理权限
	*/
	@Override
	public boolean onTouchEvent(MotionEvent event)
	{
		//return super.onTouchEvent(event);
		if (str_data__ < 5)//这里修改最小可滚动的数据点的个数
		{
			return false;
		}
		gestureDetector.onTouchEvent(event);
		return true;
	}

	class MyOnGestureListener implements GestureDetector.OnGestureListener
	{
		Handler hander_inertia = null;//手指滑动页面之后的惯性运动
		Runnable runnable_inertia = null;

		@Override
		public boolean onDown(MotionEvent e)
		{
			if (hander_inertia != null && runnable_inertia != null)
			{
				hander_inertia.removeCallbacks(runnable_inertia);
			}
			return false;
		}

		@Override
		public void onShowPress(MotionEvent e)
		{

		}

		@Override
		public boolean onSingleTapUp(MotionEvent e)
		{
			return false;
		}

		@Override
		public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
		{
			//注意：这里的distanceX是e1.getX()-e2.getX()
			//float x = e1.getX();
			//Log.i("TAG", "onScroll  distanceX: " + distanceX);

			distanceX = -distanceX;
			if (x_scroll + distanceX > max_xScroll)
			{
				x_scroll = max_xScroll;
			}
			else if (x_scroll + distanceX < min_xScroll)
			{
				x_scroll = min_xScroll;
			}
			else
			{
				x_scroll = (int) (x_scroll + distanceX);
			}


			distanceY = -distanceY;
			if (y_scroll + distanceY > max_yScroll)
			{
				y_scroll = max_yScroll;
			}
			else if (y_scroll + distanceY < min_yScroll)
			{
				y_scroll = min_yScroll;
			}
			else
			{
				y_scroll = (int) (y_scroll + distanceY);
			}
			if (hander_inertia != null && runnable_inertia != null)
			{
				hander_inertia.removeCallbacks(runnable_inertia);
			}
			//Log.i("TAG", "onScroll  x_scroll: " + x_scroll);
			//Log.i("TAG", "onScroll  y_scroll: " + y_scroll);
			invalidate();//刷新图像
			return false;
		}


		@Override
		public void onLongPress(MotionEvent e)
		{

		}

		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
		{
			//e1.getDownTime();
			//e2.getDownTime();
			Log.i("TAG", "onFling: velocityX  " + velocityX + "  velocityY  " + velocityY);

			//使用 Handler 对象和 Runnable 对象，通过每隔 x 毫秒刷新一次图像来完成滑动的图像惯性移动
			/*
			https://www.jianshu.com/p/f50074c2da20
			https://www.jianshu.com/p/44b322dfc040
			removeCallbacks		删掉任务对象
			postDelayed			定时执行一个任务对象
			post				将任务对象添加到队列
			 */
			hander_inertia = new Handler();
			final int _velocityX = (int) velocityX;
			final int _velocityY = (int) velocityY;
			runnable_inertia = new Runnable()
			{
				@Override
				public void run()
				{
					Log.i("TAG", "run: x_scroll  " + x_scroll + "  y_scroll   " + x_scroll);
					int distanceX, distanceY;
					boolean go_x = false, go_y = false;
					distanceX = _velocityX / refresh_rate;
					distanceY = _velocityY / refresh_rate;
					Log.i("TAG", "run: distanceX  " + distanceX + "  distanceY   " + distanceY);
					if (x_scroll + distanceX > max_xScroll)
					{
						x_scroll = max_xScroll;
					}
					else if (x_scroll + distanceX < min_xScroll)
					{
						x_scroll = min_xScroll;
					}
					else
					{
						go_x = true;
						x_scroll = (int) (x_scroll + distanceX);
					}

					if (y_scroll + distanceY > max_yScroll)
					{
						y_scroll = max_yScroll;
					}
					else if (y_scroll + distanceY < min_yScroll)
					{
						y_scroll = min_yScroll;
					}
					else
					{
						go_y = true;
						y_scroll = (int) (y_scroll + distanceY);
					}

					if (go_x || go_y)
					{
						hander_inertia.postDelayed(this, refresh_cycle);//1000ms / 刷新率 =帧间隔时间
					}
					else
					{
						hander_inertia.removeCallbacks(this);
					}
//					x_scroll = x_scroll + _velocityX / refresh_rate;
//					y_scroll = y_scroll + _velocityY / refresh_rate;
//					hander_inertia.postDelayed(this, refresh_cycle);//1000ms / 刷新率 =帧间隔时间

					Log.i("TAG", "run: x_scroll  " + x_scroll + "  y_scroll   " + x_scroll);
					Log.i("TAG", "run: refresh_cycle  " + refresh_cycle);
					invalidate();//刷新图像
				}
			};
			hander_inertia.postDelayed(runnable_inertia, refresh_cycle);//1000ms / 刷新率 =帧间隔时间
			return false;
		}

	}


	/**
	 * 获取文字的高度
	 *
	 * @param paint
	 * @param text
	 * @return
	 */
	private int getTextHeight(Paint paint, String text)
	{
		Rect rect = new Rect();
		paint.getTextBounds(text, 0, text.length(), rect);
		return rect.height();
	}

	public int dip2px(int dp)
	{
		float density = getContext().getResources().getDisplayMetrics().density;
		return (int) (dp * density + 0.5);
	}

	/**
	 * sp转换px
	 */
	public int sp2px(int spValue)
	{
		final float fontScale = getContext().getResources().getDisplayMetrics().scaledDensity;
		return (int) (spValue * fontScale + 0.5f);
	}
}
